﻿using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

using NUnit.Framework;
using Nemerle2.Compiler;

namespace Test
{
  /// <summary>
  /// Description of ParametersTests.
  /// </summary>
  [TestFixture]
  public class ParametersTests : AssemblyTests
  {
    private mutable _progType : ITypeInfo;

    [SetUp]
    public Prepare(): void
    {
      _progType = CommonProject.LoadedAssemblies.First().AllTypes.First ( t => t.Name == "Program" );
      Assert.NotNull(_progType);
    }

    [Test]
    public TestParams() : void
    {
      def methods = _progType.FindMethod("Method", NBindingFlags.Public);
      Assert.IsFalse(methods.IsEmpty);
      def method = methods.Head;
      Assert.NotNull(method);
      Assert.NotNull(method.Parameters);

      Assert.AreEqual(4, method.Parameters.Length);
      Assert.AreEqual(["t","x","y","z"], method.Parameters.Map(p => p.Name));
      
      def parameters = method.Parameters.ToArray();
      
      Assert.NotNull(parameters[0].Type);

      Assert.AreEqual(ParameterModifiers.This, parameters[0].Modifiers);
      Assert.AreEqual(ParameterModifiers.None, parameters[1].Modifiers);
      Assert.AreEqual(ParameterModifiers.Ref,  parameters[2].Modifiers);
      Assert.AreEqual(ParameterModifiers.Out,  parameters[3].Modifiers);
      Assert.IsFalse(method.ParameterArray.HasValue);

    }

    [Test]
    public TestParamsArray() : void
    {
      def methods = _progType.FindMethod("MethodWithParams", NBindingFlags.Public);
      Assert.IsFalse(methods.IsEmpty);
      def method = methods.Head;

      Assert.IsTrue(method.ParameterArray.HasValue);
      Assert.AreEqual("y", method.ParameterArray.Value.Name);

      ignore(method.FunType);
    }
    
    [Test]    
    public ConverterHelpersTest() : void
    {
      def methods = _progType.FindMethod("MethodWithParams", NBindingFlags.Public);
      Assert.IsFalse(methods.IsEmpty);
      def method = methods.Head;
      
      def pars = method.Parameters.ToArray();
      Assert.AreEqual(2, pars.Length);
      Assert.AreEqual(ConverterHelper.ToString(pars[0], ConvertOption.None), "x : Int32");
      //Assert.AreEqual(ConverterHelper.ToString(pars[0], ConvertOption.UseFullName), "x : System.Int32");
      //Assert.AreEqual(ConverterHelper.ToString(pars[0], ConvertOption.UseAliases), "x : int");
      Assert.AreEqual(ConverterHelper.ToString(pars[1], ConvertOption.None), "y : array[String]");
    }
  }
}
